package org.tio.sitexxx.web.server.controller.kf;



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.http.common.Cookie;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.http.server.annotation.RequestPath;
import com.qiniu.util.Auth;
import org.tio.utils.jfinal.P;

import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


@RequestPath(value = "/cloud")
public class Qn {
    private static Logger log = LoggerFactory.getLogger(Qn.class);
    private String accessKey = P.get("storage.qn.accessKey");


    private String secretKey = P.get("storage.qn.secretKey");

    private String bucket = P.get("storage.qn.bucket");

    @RequestPath("/qn/token")
    public String token(){
        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);
        return upToken;
    }

    @RequestPath("/qn/uptoken")
    public Map<String,String> uptoken(){
        System.out.println("get uptoken");
        Auth auth = Auth.create(accessKey,secretKey);
        Map<String,String> token = new HashMap<>();
        token.put("uptoken",auth.uploadToken(bucket));
        return token;
    }

    /**
     * 上传七牛文件的key
     *
     * @param type
     * @param counts
     * @return
     */
    @RequestPath("/qn/get/key")
    public List<String> getKey(String type, Integer counts) {
        if (type == null) return new ArrayList<String>() {{
            add("参数错误");
        }};
        return QnTool.keyList(type, counts);
    }

    @RequestPath("/fileinfo")
    public String fileinfo(String name, String suffix) {
        Date d = new Date();
        return d.toString() + "." + suffix;
    }

    @RequestPath("/get/encoding")
    public Object get_encoding() {
        Map<String, Object> map = new HashMap<>(4);
        map.put("para", P.get("encoding.para"));
        map.put("ok", true);
        return map;
    }

    private static class QnTool {
        private static Lock lock = new ReentrantLock();

        public static volatile long degree = 1;

        /**
         * 写成静态内部类的理由，keyList不需要应用外围类的变量  这是次要的
         * 主要的原因是我觉得，1是代码可以整洁一点，2是我还没去看tio针对@RequestPath注解在运行时通过反射做了什么，并不知道他有没有维持Qn这个类为一个单例，
         * 个人觉得，代码块被jvm加载到内存之后保持单例的话开销会小一些
         *
         * @param type
         * @param counts
         * @return  List<String>
         */
        @SuppressWarnings("all")
        public static List<String> keyList(String type, Integer counts) {
            List<String> keyList = new ArrayList<>();
            if (type == null || type.isEmpty()) return keyList;
            if (!type.equals("image")) {
                String key = "";
                try {
                    Long time = new Date().getTime();
                    lock.lock();
                    key = time + "-" + degree++;
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error(e.toString(), e);
                } finally {
                    lock.unlock();
                }
                if (type.equals("voice")) {
                    key = "a" + key + ".mp3";
                    keyList.add(key);
                } else if (type.equals("video")) {
                    key = "v" + key + ".mp4";
                    keyList.add(key);
                }
            } else {
                Long time = new Date().getTime();
                for (int i = 0; i < counts; i++) {
                    String key = "";
                    try {
                        /**
                         * 提示non-atomic operation on volatile field 非原子性操作，事实上是加了锁的  这里保持degree正常即可,
                         * 并不一定说非要保持某一个线程，执行完整个循环,才释放资源，那样效率不高
                         *
                         * 解耦合try finally/try catch 语句块
                         */
                        try{
                            lock.lock();
                            key = "p"+time + "-" + degree++ +".jpg";
                        }finally {
                            lock.unlock();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error(e.toString(), e);
                    }
                    keyList.add(key);
                }
            }
            return keyList;
        }

    }

    //test
/*    class test implements Runnable{
        private  Qn qn;
        public test(Qn qn){this.qn=qn;}
        @Override
        public void run() {
            List<String>list=qn.getKey("image",9);
            System.out.println("----------");
            list.forEach((str)-> System.out.println(Thread.currentThread().getName()+":"+str));
            System.out.println("-------------");
        }
    }
    public static void main(String[] args) {
//        QnTool.keyList("image",4);
        Qn qn=new Qn();
        Qn.test t=qn.new test(new Qn());
        Thread thread=new Thread(t,"thread");
        Thread thread2=new Thread(t,"thread2");
        Thread thread3=new Thread(t,"thread3");
        thread2.start();
        thread3.start();
        thread.start();
    }*/
}
